package com.deepexp.servicetest;

import android.app.assist.AssistStructure;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.CancellationSignal;
import android.service.autofill.AutofillService;
import android.service.autofill.Dataset;
import android.service.autofill.FillCallback;
import android.service.autofill.FillContext;
import android.service.autofill.FillRequest;
import android.service.autofill.FillResponse;
import android.service.autofill.SaveCallback;
import android.service.autofill.SaveRequest;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillValue;
import android.widget.RemoteViews;

import androidx.annotation.RequiresApi;

import java.util.ArrayList;
import java.util.List;

/**
 * Author xyh
 * create time 2021/2/5
 */
@RequiresApi(api = Build.VERSION_CODES.O)
public class MyAutoFillService extends AutofillService {
    List<AssistStructure.ViewNode > viewNodeList;

    @Override
    public void onFillRequest(FillRequest fillRequest, CancellationSignal cancellationSignal, FillCallback fillCallback) {
        List<FillContext> context = fillRequest.getFillContexts();
        AssistStructure structure = context.get(context.size() - 1).getStructure();

        viewNodeList = new ArrayList<>();

        traverseStructure(structure, viewNodeList);

        SharedPreferences sharedPreferences = getSharedPreferences("user", MODE_PRIVATE);
        String spusername = sharedPreferences.getString("username", null);
        String sppassword = sharedPreferences.getString("password", null);


        //加载自动填充的布局，可更换为自定义View
        RemoteViews usernamePresentation = new RemoteViews(getPackageName(), android.R.layout.simple_list_item_1);
        usernamePresentation.setTextViewText(android.R.id.text1, spusername);
        RemoteViews passwordPresentation = new RemoteViews(getPackageName(), android.R.layout.simple_list_item_1);
        passwordPresentation.setTextViewText(android.R.id.text1, sppassword);


        ParsedStructure parsedStructure = new ParsedStructure();
        parsedStructure.setUsernameId(viewNodeList.get(0).getAutofillId());
        parsedStructure.setPasswordId(viewNodeList.get(1).getAutofillId());

        //构建填充的数据
        FillResponse fillResponse = new FillResponse.Builder()
                .addDataset(new Dataset.Builder()
                        .setValue(ParsedStructure.usernameId,
                                AutofillValue.forText(spusername), usernamePresentation)
                        .setValue(ParsedStructure.passwordId,
                                AutofillValue.forText(sppassword), passwordPresentation)
                        .build())
                .build();
        fillCallback.onSuccess(fillResponse);


    }


    @Override
    public void onSaveRequest(SaveRequest saveRequest, SaveCallback saveCallback) {

        // Get the structure from the request
        List<FillContext> context = saveRequest.getFillContexts();
        AssistStructure structure = context.get(context.size() - 1).getStructure();

        // Traverse the structure looking for data to save
        traverseStructure(structure, viewNodeList);

        // Persist the data, if there are no errors, call onSuccess()
        saveCallback.onSuccess();
}



    public void traverseStructure(AssistStructure structure, List viewNodeList) {
        int nodes = structure.getWindowNodeCount();

        for (int i = 0; i < nodes; i++) {
            AssistStructure.WindowNode windowNode = structure.getWindowNodeAt(i);
            AssistStructure.ViewNode viewNode = windowNode.getRootViewNode();
            traverseNode(viewNode, viewNodeList);
        }
    }


    public void traverseNode(AssistStructure.ViewNode viewNode, List viewNodeList) {
        if (viewNode.getAutofillHints() != null && viewNode.getAutofillHints().length > 0) {
            // If the client app provides autofill hints, you can obtain them using:
            // viewNode.getAutofillHints();
            return;
        } else {
            // Or use your own heuristics to describe the contents of a view
            // using methods such as getText() or getHint().

            //遍历EditText布局
            if (viewNode.getClassName().contains("EditText")) {
                String viewId = viewNode.getIdEntry();
                if (viewId != null && (viewId.contains("username") || viewId.contains("username") || viewId.contains("password"))) {

                    //添加到list
                    viewNodeList.add(viewNode);

                    return;
                }
            }


        }

        for (int i = 0; i < viewNode.getChildCount(); i++) {
            AssistStructure.ViewNode childNode = viewNode.getChildAt(i);
            traverseNode(childNode, viewNodeList);
        }
    }

    static class ParsedStructure {
        static AutofillId usernameId;
        static AutofillId passwordId;

        public AutofillId getPasswordId() {
            return passwordId;
        }

        public void setPasswordId(AutofillId passwordId) {
            ParsedStructure.passwordId = passwordId;
        }

        public AutofillId getUsernameId() {
            return usernameId;
        }

        public void setUsernameId(AutofillId usernameId) {
            this.usernameId = usernameId;
        }
    }
}
